﻿namespace KWT.DRG_DIP.DO.Group.DRGGroup
{
    public partial class DRGGroup : DRGGroupBase
    {
        /// <summary>
        /// 获得DRG分组
        /// </summary>
        /// <param name="inputPara"></param>
        /// <returns></returns>
        public override DRGGroupResult GetDrg(DRGGroupInputPara inputPara)
        {
            DRGGroupResult result = new DRGGroupResult();

            //获得对应的ADRG
            result = GetAdrg(inputPara);
            //无法确定MDC
            if (!result.Success && result.strResult == "0000")
            {
                return result;
            }
            //确定了MDC，但无法确认是那个ADRG，只有内科组有可能
            //外科组确定了MDC，分不了ADRG，入QY
            if (result.strResult.Length == 1)
            {
                result.Success = false;
                result.msg = $"已确定MDC为{result.strResult};" + result.msg;
                return result;
            }
            //获得DRG，不需再进行分组
            if (result.strResult.Length == 4)
            {
                return result;
            }
            return GetDrg(inputPara, result);
        }


        #region 获得ADRG
        /// <summary>
        /// 获得ADRG
        /// </summary>
        /// <param name="inputPara"></param>
        /// <returns></returns>
        private DRGGroupResult GetAdrg(DRGGroupInputPara inputPara)
        {
            DRGGroupResult result = new DRGGroupResult();
            string MDC = "";
            #region  数据验证
            if (inputPara.diagnoses == null || inputPara.diagnoses.Count == 0)
            {
                result.Success = false;
                result.msg = $"无主诊断";
                return result;
            }

            //主诊断 
            var MainDiagnose = GetDiagnoseMain(inputPara.diagnoses);
            if (MainDiagnose == null)
            {
                result.Success = false;
                result.msg = $"无主诊断";
                return result;
            }
            //主手术
            var MainOperation = GetOperationMain(inputPara.operation);

            #endregion

            //MDCA：器官或骨髓移植、有创呼吸机使用超过96小时、使用ECMO或人工心脏
            //MDCP：新生儿年龄小于29天或源于新生儿诊断的婴儿病例（29天＜出生年龄＜1周岁）
            //MDCY：主要诊断或其他诊断为HIV的病例
            //MDCZ：发生两处及以上的严重创伤 （《CHS - DRG2.0国家版》表中sheet“RuleMDC”中“Z01 - Z09”  每一个代表一个部位的严重创伤诊断合集）

            #region  是否有手术，有手术，首先判断是否是MDCA
            if (inputPara.operation != null && inputPara.operation.Count > 0)
            {
                //有手术，且是MDCA
                if (ruleADRGs.Any(x => x.MDC == "A" && inputPara.operation.Any(y => x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
                {
                    MDC = "A";
                    result = ADRG_Other(inputPara, MDC, MainDiagnose, MainOperation);
                    if (!result.strResult.EndsWith("QY"))
                    {
                        return result;
                    }
                }

            }
            #endregion

            #region 无手术 或者 有手术且不是MDCA 年龄是小于1周岁,使用MDCP逻辑
            if (inputPara.ageUnit == 0 && inputPara.age < 365)
            {
                MDC = "P";
                result = ADRG_P(inputPara, MainDiagnose, MainOperation);
                return result;
            }
            #endregion

            #region 不是 MDCP，再确认是否是MDCY

            //任一诊断是否是 MDC Y
            if (ruleMDCs.Any(x => x.MDC == "Y" && inputPara.diagnoses.Any(y => x.code.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
            {
                MDC = "Y";
                return ADRG_Other(inputPara, MDC, MainDiagnose, MainOperation);
            }

            #endregion

            #region 不是 MDCY，再确认是否是MDCZ

            int count = ruleMDCs.FindAll(x => x.MDC.StartsWith("Z") && inputPara.diagnoses.Any(y => x.code.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))).GroupBy(x => x.MDC).Count();

            if (count >= 2)
            {
                MDC = "Z";
                return ADRG_Other(inputPara, MDC, MainDiagnose, MainOperation);
            }

            #endregion

            #region 以上均不能确定MDC ，根据主诊断确定   
            var rule_MDC = ruleMDCs.FirstOrDefault(x => x.code.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase));

            if (rule_MDC == null)
            {
                MDC = "";
            }
            else
            {
                MDC = rule_MDC.MDC;
            }
            if (MDC.StartsWith("Z"))
            {
                MDC = "Z";
            }
            if (string.IsNullOrEmpty(MDC))
            {
                result.Success = false;
                result.msg = "无法确定MDC";
                result.strResult = "0000";
                return result;
            }
            else
            {
                return ADRG_Other(inputPara, MDC, MainDiagnose, MainOperation);
            }
            #endregion
        }

        #region 根据MDCP逻辑 判断入组
        /// <summary>
        /// 根据MDCP逻辑 判断入组
        /// 年龄小于1周岁
        /// </summary>
        /// <param name="inputPara"></param>
        /// <returns></returns>
        private DRGGroupResult ADRG_P(DRGGroupInputPara inputPara, Diagnose MainDiagnose, Operation? MainOperation)
        {
            DRGGroupResult result = new DRGGroupResult();

            #region step1： 29≤出生年龄＜365
            if (inputPara.age >= 29)
            {
                if (ruleADRGs.Any(x => x.ADRGCode == "PV1" && x.ICDCode.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "29≤出生年龄＜365 且主诊断在PV1诊断列表";
                    result.strResult = "PV1";
                    return result;
                }
                else
                {
                    result.Success = false;
                    result.msg = "主诊断与天龄冲突";
                    result.strResult = "0000";
                    return result;
                }
            }
            #endregion

            #region step2： 0≤天龄＜29 且手术不为空
            if (inputPara.operation != null && inputPara.operation.Count > 0)
            {
                if (ruleADRGs.Any(x => x.ADRGCode == "PB1" && x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术与PB1手术集有交集";
                    result.strResult = "PB1";
                    return result;
                }

                if (ruleADRGs.Any(x => x.ADRGCode == "PC1" && x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术与PC1手术集有交集";
                    result.strResult = "PC1";
                    return result;
                }

                if (ruleADRGs.Any(x => x.ADRGCode == "PD1" && x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术与PD1手术集有交集";
                    result.strResult = "PD1";
                    return result;
                }
                if (ruleADRGs.Any(x => x.ADRGCode == "PJ1" && x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术与PJ1手术集有交集";
                    result.strResult = "PJ1";
                    return result;
                }
                if (ruleADRGs.Any(x => x.ADRGCode == "PK1" && x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术与PK1手术集有交集";
                    result.strResult = "PK1";
                    return result;
                }

                if (rule_NotOperations.Any(x => x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
                {
                    result.Success = true;
                    result.msg = "0≤天龄＜29 且主手术在“不作为手术”列表";
                    result.strResult = "PQY";
                    return result;
                }
            }
            #endregion

            #region step3: 【0≤天龄＜29】 且【手术为空 或者 手术不为空，但不满足step2】

            if (ruleADRGs.Any(x => x.ADRGCode == "PR1" && x.ICDCode.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
            {
                result.Success = true;
                result.msg = "0≤天龄＜29 且主诊断在PR1诊断列表";
                result.strResult = "PR1";
                return result;
            }

            if (ruleADRGs.Any(x => x.ADRGCode == "PU1" && x.ICDCode.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)))
            {
                result.Success = true;
                result.msg = "0≤天龄＜29 且主诊断在PU1诊断列表";
                result.strResult = "PU1";
                return result;
            }

            #endregion

            #region 【0≤天龄＜29】 且【手术为空 或者 手术不为空，但不满足step3】，根据体重进行分组
            switch (inputPara.bornWeight)
            {
                case >= 0 and < 1500:
                    result = GetADRG_PS(inputPara, "PS1");
                    break;
                case >= 1500 and <= 1999:

                    result = GetADRG_PS(inputPara, "PS2");
                    break;

                case >= 2000 and <= 2499:
                    result = GetADRG_PS(inputPara, "PS3");
                    break;
                case > 2499:
                    result = GetADRG_PS(inputPara, "PS4");
                    break;
                default:
                    result.Success = true;
                    result.msg = $"诊断与天龄冲突";
                    result.strResult = "0000";
                    break;
            }
            return result;
            #endregion

        }

        #region 判断 任一诊断是否在 PS1-4 诊断列表中
        /// <summary>
        /// 判断 任一诊断是否在 PS1-4 诊断列表中
        /// </summary>
        /// <param name="inputPara"></param>
        /// <param name="adrg"></param>
        /// <returns></returns>
        private DRGGroupResult GetADRG_PS(DRGGroupInputPara inputPara, string adrg)
        {
            DRGGroupResult result = new DRGGroupResult();

            if (ruleADRGs.Any(x => x.ADRGCode == adrg && inputPara.diagnoses.Any(y => x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
            {
                result.Success = true;
                result.msg = $"0≤天龄＜29 且任一诊断在{adrg}诊断列表";
                result.strResult = adrg;
                return result;
            }
            else
            {
                result.Success = false;
                result.msg = $"诊断与体重冲突，展示{adrg}诊断列表";
                result.strResult = "0000";
                return result;
            }
        }
        #endregion

        #endregion

        #region 根据MDC@逻辑 判断入组
        /// <summary>
        /// 根据MDC@逻辑 判断入组
        /// </summary>
        /// <param name="inputPara"></param>
        /// <param name="MDC"></param>
        /// <param name="MainDiagnose"></param>
        /// <param name="MainOperation"></param>
        /// <returns></returns>
        private DRGGroupResult ADRG_Other(DRGGroupInputPara inputPara, string MDC, Diagnose MainDiagnose, Operation? MainOperation)
        {
            DRGGroupResult result = new DRGGroupResult();
            List<Rule_ADRG> ruleADRGsMDC = ruleADRGs.FindAll(x => x.MDC == MDC);

            //所有手术均在 “不作为手术列表”，入内科组
            bool bNotOperations = inputPara.operation.All(x => rule_NotOperations.Any(y => y.ICDCode.Equals(x.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)));

            #region step0 :特殊处理

            result = GetADRGSpecial(inputPara, MDC, MainDiagnose, bNotOperations);
            if (result.Success)
                return result;
            #endregion

            #region step1: 手术为空，入内科组
            //手术为空，入内科组
            if (inputPara.operation == null || inputPara.operation.Count == 0 || bNotOperations)
            {
                var adrg = ruleADRGsMDC.FirstOrDefault(x => x.ICDCode.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)
                            && x.GroupCategory == "内科组");
                if (MDC == "Y")
                {
                    adrg = ruleADRGsMDC.FirstOrDefault(x => inputPara.diagnoses.Any(y => y.medicalInsuranceCode.Equals(x.ICDCode, StringComparison.OrdinalIgnoreCase))
                            && x.GroupCategory == "内科组");
                }
                if (adrg != null)
                {
                    if (inputPara.operation == null || inputPara.operation.Count == 0)
                    {
                        result.msg = $"手术为空，入内科组,ADRG确认为{adrg.ADRGCode}";
                    }
                    else
                    {
                        result.msg = $"手术均在“不作为手术列表”，入内科组,ADRG确认为{adrg.ADRGCode}";
                    }
                    result.Success = true;

                    result.strResult = adrg.ADRGCode;
                    return result;
                }
                else
                {
                    result.Success = false;
                    result.strResult = MDC;
                    result.msg = $"内科组，主诊断【{MainDiagnose.medicalInsuranceCode}】选择错误，无法确定ADRG";
                    return result;
                }
            }
            #endregion

            #region step2.1 :手术不为空,判断是否是 主诊断+主手术(0-1个)+手术（1-n个）
            string? strAdrg = "";
            List<AdrgResult> lstAdrgResult = GetADRG1(ruleADRGsMDC, MainDiagnose, inputPara.diagnoses, inputPara.operation);
            //多手术，条件多优先，含主手术优先，adrg名称排序
            strAdrg = lstAdrgResult.Where(x => x.OperationCount > 1)
                                    .OrderByDescending(x => x.ConditionCount)
                                    .ThenByDescending(x => x.IsContaintMain)
                                    .ThenBy(x => x.adrgcode).FirstOrDefault()?.adrgcode;
            if (strAdrg == null)
            {
                strAdrg = "";
            }
            if (!string.IsNullOrEmpty(strAdrg))
            {
                result.Success = true;
                result.msg = $"ADRG已确认{strAdrg}:主诊断+多手术组";
                result.strResult = strAdrg;
                return result;
            }
            #endregion

            #region step2.2 :手术不为空,判断是否是 手术组合(多手术)：主手术+其他手术+诊断0-n个
            //手术组合(多手术):条件多优先，主手术优先,adrg名称排序
            List<AdrgResult> lstAdrgResultOperation = GetADRG2(ruleADRGsMDC, inputPara.diagnoses, inputPara.operation);
            strAdrg = lstAdrgResultOperation.Where(x => x.OperationCount > 1)
                                                            .OrderByDescending(x => x.ConditionCount)
                                                            .ThenByDescending(x => x.IsContaintMain)
                                                            .ThenBy(x => x.adrgcode).FirstOrDefault()?.adrgcode;
            if (!string.IsNullOrEmpty(strAdrg))
            {
                result.Success = true;
                result.msg = $"ADRG已确认{strAdrg}:手术组合";
                result.strResult = strAdrg;
                return result;
            }
            #endregion

            #region step2.3 :手术不为空,判断是否是 主诊断+手术(主手术优先)
            //单手术，条件多优先，主手术优先,adrg名称排序
            strAdrg = lstAdrgResult.Where(x => x.OperationCount == 1)
                                            .OrderByDescending(x => x.ConditionCount)
                                            .ThenByDescending(x => x.IsContaintMain)
                                            .ThenBy(x => x.adrgcode).FirstOrDefault()?.adrgcode;
            if (strAdrg == null)
            {
                strAdrg = "";
            }
            if (!string.IsNullOrEmpty(strAdrg))
            {
                result.Success = true;
                result.msg = $"ADRG已确认{strAdrg}:主诊断+手术";
                result.strResult = strAdrg;
                return result;
            }
            #endregion

            #region step2.4 :根据主手术，无分组条件找出 ADRG 组
            //根据主手术，无分组条件找出 ADRG 组
            strAdrg = GetADRG4(ruleADRGsMDC, MainOperation);
            if (!string.IsNullOrEmpty(strAdrg))
            {
                result.Success = true;
                result.msg = $"ADRG已确认{strAdrg}:主手术";
                result.strResult = strAdrg;
                return result;
            }
            #endregion

            #region step2.4 :根据主诊断，无分组条件找出 ADRG 组
            ////根据主手术，无分组条件找出 ADRG 组
            //strAdrg = GetADRG5(ruleADRGsMDC, MainDiagnose);
            //if (!string.IsNullOrEmpty(strAdrg))
            //{
            //    result.Success = true;
            //    result.msg = $"ADRG已确认{strAdrg}:主诊断";
            //    result.strResult = strAdrg;
            //    return result;
            //}

            #endregion

            #region step2.5 : 入@QY
            //无法分出ADRG 入歧义组
            strAdrg = $"{MDC}QY"; ;

            result.Success = true;
            result.msg = $"ADRG入{strAdrg}";
            result.strResult = strAdrg;
            return result;
            #endregion

        }

        #endregion

        #endregion

        #region DRG末位编码
        //DRG末位编码：
        //9   代表未做区分
        //1  伴严重合并症或并发症：其他诊断属于MCC，且不在主诊断对应的排除列表中
        //3  伴一般合并症或并发症：其他诊断属于CC，且不在主诊断对应的排除列表中
        //5  不伴合并症或并发症
        //0  小于17岁组

        //注意：
        //部分ADRG组下仅有1，5，则将 3，5合并为5
        //部分ADRG组下仅有3，5，则将 1，3合并为3
        //部分ADRG组下仅有1，3，则将 3，5合并为3
        //部分地市的目录末位编码会超过1，3，5，9，0的范畴，这时需要根据该组的中文含义调整入组逻辑，

        /// <summary>
        /// DRG末位编码
        /// </summary>
        /// <param name="inputPara"></param>
        /// <param name="adrgResult"></param>
        /// <returns></returns>
        private DRGGroupResult GetDrg(DRGGroupInputPara inputPara, DRGGroupResult adrgResult)
        {
            DRGGroupResult result = new DRGGroupResult();
            if (adrgResult.strResult.EndsWith("QY"))
            {
                result.Success = true;
                result.msg = adrgResult.msg;
                result.strResult = adrgResult.strResult;
                return result;
            }

            //该ADRG 分组下对应的drgs
            var drgs = rule_DRGs.Where(x => x.ADRG == adrgResult.strResult).ToList();

            #region “9”组": 该ADRG下有“9”组"
            if (drgs.Any(x => x.drgCode.EndsWith("9")))
            {
                result.Success = true;
                result.msg = adrgResult.msg + "；入“9”组";
                result.strResult = adrgResult.strResult + "9"; ;
                return result;
            }
            #endregion

            #region “0”组":小于17周岁
            //小于17周岁
            if ((inputPara.ageUnit == 0 && inputPara.age < 365) || (inputPara.ageUnit == 1 && inputPara.age < 17))
            {
                if (drgs.Any(x => x.drgCode.EndsWith("0")))
                {

                    result.Success = true;
                    result.msg = adrgResult.msg + "；小于17周岁，入“0”组";
                    result.strResult = adrgResult.strResult + "0"; ;
                    return result;
                }
            }
            #endregion

            #region 1,3,5 合并分组情况
            //部分ADRG组下仅有1，5，则将 3，5合并为5
            //部分ADRG组下仅有3，5，则将 1，3合并为3
            //部分ADRG组下仅有1，3，则将 3，5合并为3

            #region 任一其他诊断属于MCC，且主诊断不在对应的排除列表
            //其他诊断属于MCC
            List<Rule_MCC> lstMcc = rule_MCCs.FindAll(x => inputPara.diagnoses.Any(y => y.IsMain == 0 && x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)));
            bool bMcc = false;
            //其他诊断属于MCC，且主诊断不在对应的排除列表                
            foreach (var mcc in lstMcc)
            {
                if (!rule_Excludes.Any(x => x.excludeGroup == mcc.excludeGroup
                    && inputPara.diagnoses.Any(y => y.IsMain == 1 && x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
                {
                    bMcc = true;
                    break;
                }
            }
            if (bMcc)
            {
                if (drgs.Any(x => x.drgCode.EndsWith("1")))
                {
                    result.Success = true;
                    result.msg = adrgResult.msg + "；任一其他诊断属于MCC，且主诊断不在对应的排除列表，入“1”组";
                    result.strResult = adrgResult.strResult + "1";
                    return result;
                }
                else if (drgs.Any(x => x.drgCode.EndsWith("3")))
                {

                    result.Success = true;
                    result.msg = adrgResult.msg + "；任一其他诊断属于MCC，且主诊断不在对应的排除列表，没有“1”组，入“3”组";
                    result.strResult = adrgResult.strResult + "3";
                    return result;
                }
                else if (drgs.Any(x => x.drgCode.EndsWith("5")))
                {
                    result.Success = true;
                    result.msg = adrgResult.msg + "；任一其他诊断属于MCC，且主诊断不在对应的排除列表，没有“1”,“3”组，入“5”组";
                    result.strResult = adrgResult.strResult + "5";
                    return result;
                }
            }
            #endregion

            #region 任一其他诊断属于CC，且主诊断不在对应的排除列表
            List<Rule_CC> lstCc = rule_CCs.FindAll(x => inputPara.diagnoses.Any(y => y.IsMain == 0 && x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)));
            bool bCc = false;
            //其他诊断属于CC，且主诊断不在对应排除列表
            foreach (var mcc in lstCc)
            {
                if (!rule_Excludes.Any(x => x.excludeGroup == mcc.excludeGroup
                    && inputPara.diagnoses.Any(y => y.IsMain == 1 && x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
                {
                    bCc = true;
                    break;
                }
            }
            if (bCc)
            {
                if (drgs.Any(x => x.drgCode.EndsWith("3")))
                {
                    result.Success = true;
                    result.msg = adrgResult.msg + "；任一其他诊断属于CC，且主诊断不在对应的排除列表，入“3”组";
                    result.strResult = adrgResult.strResult + "3";
                    return result;
                }
                else if (drgs.Any(x => x.drgCode.EndsWith("5")))
                {

                    result.Success = true;
                    result.msg = adrgResult.msg + "；任一其他诊断属于CC，且主诊断不在对应的排除列表，没有“3”组，入“5”组";
                    result.strResult = adrgResult.strResult + "5";
                    return result;
                }
            }
            #endregion

            #region 不在“1”,“3”组，入“5”组"
            if (drgs.Any(x => x.drgCode.EndsWith("5")))
            {
                result.Success = true;
                result.msg = adrgResult.msg + "；不在“1”,“3”组，入“5”组";
                result.strResult = adrgResult.strResult + "5";
                return result;
            }
            else if (drgs.Any(x => x.drgCode.EndsWith("3")))
            {

                result.Success = true;
                result.msg = adrgResult.msg + "；没有“5”组，入“3”组";
                result.strResult = adrgResult.strResult + "3";
                return result;
            }
            else if (drgs.Any(x => x.drgCode.EndsWith("1")))
            {

                result.Success = true;
                result.msg = adrgResult.msg + "；没有“3”，“5”组，入“1”组";
                result.strResult = adrgResult.strResult + "1";
                return result;
            }
            #endregion

            #endregion

            result.Success = false;
            result.msg = adrgResult.msg + "；未能分组";
            result.strResult = adrgResult.strResult + " "; //未能分组，返回ADRG
            return result;
        }
        #endregion

        #region  私有函数，ADRG 分步骤分组

        #region 获得主诊断
        /// <summary>
        /// 获得主诊断
        /// </summary>
        /// <param name="lstDiagnose"></param>
        /// <returns></returns>
        private Diagnose? GetDiagnoseMain(List<Diagnose> lstDiagnose)
        {
            if (lstDiagnose == null || lstDiagnose.Count == 0)
            {
                return null;
            }
            //主诊断 
            var MainDiagnose = lstDiagnose.FindAll(x => x.IsMain == 1);
            if (MainDiagnose == null || MainDiagnose.Count == 0)
            {
                lstDiagnose[0].IsMain = 1;
                return lstDiagnose[0];
            }
            else if (MainDiagnose.Count == 1)
            {
                return MainDiagnose[0];
            }
            else
            {
                var temp = MainDiagnose[0];
                foreach (var item in lstDiagnose)
                {
                    item.IsMain = 0;
                    if (item.medicalInsuranceCode == temp.medicalInsuranceCode)
                    {
                        item.IsMain = 1;
                    }
                }
                return temp;
            }
        }
        #endregion

        #region 获得主手术
        /// <summary>
        /// 获得主手术
        /// </summary>
        /// <param name="lstOperation"></param>
        /// <returns></returns>
        private Operation? GetOperationMain(List<Operation> lstOperation)
        {
            if (lstOperation == null || lstOperation.Count == 0)
            {
                return null;
            }
            //主手术 
            var MainOperation = lstOperation.FindAll(x => x.IsMain == 1);
            if (MainOperation == null || MainOperation.Count == 0)
            {
                lstOperation[0].IsMain = 1;
                return lstOperation[0];
            }
            else if (MainOperation.Count == 1)
            {
                return MainOperation[0];
            }
            else
            {
                var temp = MainOperation[0];
                foreach (var item in lstOperation)
                {
                    item.IsMain = 0;
                    if (item.medicalInsuranceCode == temp.medicalInsuranceCode)
                    {
                        item.IsMain = 1;
                    }
                }
                return temp;
            }
        }
        #endregion

        #region 主诊断+手术（多个）
        /// <summary>
        /// 主诊断+手术（多个）:多个adrg
        /// </summary>
        private List<AdrgResult> GetADRG1(List<Rule_ADRG> rules, Diagnose MainDiagnose, List<Diagnose> lstDiagnose, List<Operation> lstOperation)
        {

            #region 根据主诊断获得 adrg 列表
            var lstFindADRG = rules.FindAll(x => x.ICDCode.Equals(MainDiagnose.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase) && x.CombinationConditions != "");
            if (lstFindADRG == null || lstFindADRG.Count == 0)
            {
                return new List<AdrgResult>();
            }
            #endregion

            #region 遍历adrg 列表，获得符合全部条件的adrg
            List<AdrgResult> lstAdrgResult = new List<AdrgResult>();

            foreach (var item in lstFindADRG)
            {
                if (string.IsNullOrEmpty(item.CombinationConditions))
                {
                    continue;
                }
                //组合分组条件 或
                if (item.CombinationConditions.Contains("或"))
                {
                    List<string> strConditions = item.CombinationConditions.Split("或").ToList();

                    foreach (var condition in strConditions)
                    {
                        AdrgResult adrgResult = GetADRGByCondition(rules, condition, item.ADRGCode, lstDiagnose, lstOperation);
                        if (!string.IsNullOrEmpty(adrgResult.adrgcode))
                        {
                            lstAdrgResult.Add(adrgResult);
                        }
                    }
                }
                else
                {
                    //组合分组条件 且
                    AdrgResult adrgResult = GetADRGByCondition(rules, item.CombinationConditions, item.ADRGCode, lstDiagnose, lstOperation);
                    if (!string.IsNullOrEmpty(adrgResult.adrgcode))
                    {
                        lstAdrgResult.Add(adrgResult);
                    }
                }
            }
            #endregion

            return lstAdrgResult;
        }
        #endregion

        #region 手术+其他手术
        /// <summary>
        /// 手术+其他手术
        /// </summary>
        private List<AdrgResult> GetADRG2(List<Rule_ADRG> rules, List<Diagnose> lstDiagnose, List<Operation> lstOperation)
        {
            #region 根据手术获得 adrg 列表
            //var lstFindADRG = rules.FindAll(x => x.ICDCode == MainOperation.medicalInsuranceCode && x.CombinationConditions != "");
            var lstFindADRG = rules.FindAll(x => lstOperation.Any(y => x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)) && x.CombinationConditions != "");
            if (lstFindADRG == null || lstFindADRG.Count == 0)
            {
                return new List<AdrgResult>();
            }
            #endregion

            #region 遍历adrg 列表，获得符合全部条件的adrg
            List<AdrgResult> lstAdrgResult = new List<AdrgResult>();

            foreach (var item in lstFindADRG)
            {
                if (string.IsNullOrEmpty(item.CombinationConditions))
                {
                    continue;
                }
                //组合分组条件 或
                if (item.CombinationConditions.Contains("或"))
                {
                    List<string> strConditions = item.CombinationConditions.Split("或").ToList();

                    foreach (var condition in strConditions)
                    {
                        AdrgResult adrgResult = GetADRGByCondition(rules, condition, item.ADRGCode, lstDiagnose, lstOperation);
                        if (!string.IsNullOrEmpty(adrgResult.adrgcode))
                        {
                            lstAdrgResult.Add(adrgResult);
                        }
                    }
                }
                else
                {
                    //组合分组条件 且
                    AdrgResult adrgResult = GetADRGByCondition(rules, item.CombinationConditions, item.ADRGCode, lstDiagnose, lstOperation);
                    if (!string.IsNullOrEmpty(adrgResult.adrgcode))
                    {
                        lstAdrgResult.Add(adrgResult);
                    }
                }
            }
            #endregion

            return lstAdrgResult;
        }
        #endregion        

        #region 根据主手术，无分组条件找出 ADRG 组
        /// <summary>
        /// 根据主手术，无分组条件找出 ADRG 组
        /// </summary>
        private string GetADRG4(List<Rule_ADRG> rules, Operation? MainOperation)
        {
            // 根据主手术获得 adrg 列表
            var lstFindADRG = rules.FindAll(x => x.ICDCode.Equals(MainOperation?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase) && x.CombinationConditions == "");
            if (lstFindADRG == null || lstFindADRG.Count == 0)
            {
                return "";
            }
            else
            {
                return lstFindADRG[0].ADRGCode;
            }
        }
        #endregion

        #region 根据主诊断，无分组条件找出 ADRG 组
        /// <summary>
        /// 根据主手术，无分组条件找出 ADRG 组
        /// </summary>
        private string GetADRG5(List<Rule_ADRG> rules, Diagnose MainDiagnose)
        {
            // 根据主手术获得 adrg 列表
            var lstFindADRG = rules.FindAll(x => x.ICDCode.Equals(MainDiagnose?.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase) && x.CombinationConditions == "");
            if (lstFindADRG == null || lstFindADRG.Count == 0)
            {
                return "";
            }
            else
            {
                return lstFindADRG[0].ADRGCode;
            }
        }
        #endregion

        #region 几个特殊分组，特殊处理
        /// <summary>
        /// 几个特殊分组，特殊处理
        /// </summary>
        private DRGGroupResult GetADRGSpecial(DRGGroupInputPara inputPara, string MDC, Diagnose MainDiagnose, bool bNotOperations)
        {
            DRGGroupResult result = new DRGGroupResult();
            //符合MDCZ诊断表，且无手术或操作 adrg=ZZ1
            if (MDC == "Z" && (inputPara.operation?.Count == 0 || bNotOperations))
            {
                result.Success = true;
                result.strResult = "ZZ1";
                result.msg = $"主诊断符合MDCZ诊断表，且无手术或操作，ADRG确定为ZZ1 ";
                return result;
            }

            if (MDC == "S" && inputPara.operation?.Count > 0 && !bNotOperations)
            {
                result.Success = true;
                result.msg = $"主诊断符合MDCS主诊表的所有手术操作,ADRG确认为SB1";
                result.strResult = "SB1";
                return result;
            }
            if (MDC == "T" && inputPara.operation?.Count > 0 && !bNotOperations)
            {
                result.Success = true;
                result.msg = $"主诊断符合MDCT主诊表的所有手术操作,ADRG确认为TB1";
                result.strResult = "TB1";
                return result;
            }

            if (MDC == "X" && inputPara.operation?.Count > 0 && !bNotOperations)
            {
                result.Success = true;
                result.msg = $"主诊断符合MDCT主诊表的所有手术操作,ADRG确认为XJ1";
                result.strResult = "XJ1";
                return result;
            }

            if (MDC == "Y" && inputPara.operation?.Count > 0 && !bNotOperations)
            {
                result.Success = true;
                result.msg = $"主诊断符合MDCT主诊表的所有手术操作,ADRG确认为YC1";
                result.strResult = "YC1";
                return result;
            }

            result.Success = false;
            result.msg = "";
            result.strResult = "";
            return result;
        }
        #endregion

        #region 根据分组条件获得adrg code
        /// <summary>
        /// 根据分组条件获得adrg code
        /// </summary>
        /// <param name="rules"></param>
        /// <param name="Conditions"></param>
        /// <param name="adrgcode"></param>
        /// <returns></returns>
        private AdrgResult GetADRGByCondition(List<Rule_ADRG> rules, string Conditions, string adrgcode, List<Diagnose> lstDiagnose, List<Operation> lstOperation)
        {
            List<string> lstConditions = Conditions.Split("+").ToList();
            int ConditionCount = lstConditions.Count;
            int OperationCount = 0;
            int OperationMain = 0;
            foreach (var condition in lstConditions)
            {
                if (condition.Contains("手术"))
                {

                    //该ADRG 分组下，该condition分组标签下，包含手术组中哪些手术
                    var OperationTemp = rules.FindAll(x => x.ADRGCode == adrgcode && x.Conditions == condition && lstOperation.Any(y => x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase)));

                    //如果不包含，说明该分组条件不满足
                    if (OperationTemp == null || OperationTemp.Count == 0)
                    {
                        return new AdrgResult()
                        {
                            adrgcode = "",
                            ConditionCount = ConditionCount
                        };
                    }
                    //如果包含，确定是否包含主手术
                    if (OperationTemp.Any(x => lstOperation.Any(y => y.medicalInsuranceCode == x.ICDCode && y.IsMain == 1)))
                    {
                        OperationMain = 1;
                    }
                    OperationCount++;
                }
                if (condition.Contains("诊断"))
                {                    //该ADRG 分组下，该condition分组标签下，诊断组中包含哪些诊断
                    if (!rules.Any(x => x.ADRGCode == adrgcode && x.Conditions == condition && lstDiagnose.Any(y => x.ICDCode.Equals(y.medicalInsuranceCode, StringComparison.OrdinalIgnoreCase))))
                    {
                        return new AdrgResult()
                        {
                            adrgcode = "",
                            ConditionCount = ConditionCount
                        };
                    }
                }
            }

            return new AdrgResult()
            {
                adrgcode = adrgcode,
                ConditionCount = ConditionCount,
                OperationCount = OperationCount,
                IsContaintMain = OperationMain
            };
        }
        #endregion

        #endregion
    }
}
